﻿#include "StringUtils.h"
#include <Windows.h>

namespace StringUtils {

    // ================= 编码检测实现 (全部使用Windows API) =================

    bool IsValidUTF8(const uint8_t* data, size_t size) {
        if (!data || size == 0) return true;

        int result = MultiByteToWideChar(
            CP_UTF8,
            MB_ERR_INVALID_CHARS,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            nullptr,
            0
        );

        return result > 0 || GetLastError() != ERROR_NO_UNICODE_TRANSLATION;
    }

    bool IsValidUTF8(std::string_view sv) {
        return IsValidUTF8(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    bool IsValidUTF8(std::basic_string_view<uint8_t> sv) {
        return IsValidUTF8(sv.data(), sv.size());
    }

    bool IsValidUTF8(const char* str) {
        return str ? IsValidUTF8(reinterpret_cast<const uint8_t*>(str), strlen(str)) : true;
    }

    bool IsValidUTF8(const std::vector<uint8_t>& data) {
        return IsValidUTF8(data.data(), data.size());
    }

    bool IsValidGBK(const uint8_t* data, size_t size) {
        if (!data || size == 0) return true;

        int result = MultiByteToWideChar(
            936,  // GBK代码页
            MB_ERR_INVALID_CHARS,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            nullptr,
            0
        );

        return result > 0 || GetLastError() != ERROR_NO_UNICODE_TRANSLATION;
    }

    bool IsValidGBK(std::string_view sv) {
        return IsValidGBK(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    bool IsValidGBK(std::basic_string_view<uint8_t> sv) {
        return IsValidGBK(sv.data(), sv.size());
    }

    bool IsValidGBK(const char* str) {
        return str ? IsValidGBK(reinterpret_cast<const uint8_t*>(str), strlen(str)) : true;
    }

    bool IsValidGBK(const std::vector<uint8_t>& data) {
        return IsValidGBK(data.data(), data.size());
    }

    bool IsValidUTF16(const char16_t* data, size_t size) {
        if (!data || size == 0) return true;

        int result = WideCharToMultiByte(
            CP_UTF8,
            WC_ERR_INVALID_CHARS,
            reinterpret_cast<LPCWCH>(data),
            static_cast<int>(size),
            nullptr,
            0,
            nullptr,
            nullptr
        );

        return result > 0 || GetLastError() != ERROR_NO_UNICODE_TRANSLATION;
    }

    bool IsValidUTF16(std::u16string_view sv) {
        return IsValidUTF16(sv.data(), sv.size());
    }

    bool IsValidUTF16(const std::vector<char16_t>& data) {
        return IsValidUTF16(data.data(), data.size());
    }

    bool IsValidWideChar(const wchar_t* data, size_t size) {
        return IsValidUTF16(reinterpret_cast<const char16_t*>(data), size);
    }

    bool IsValidWideChar(std::wstring_view sv) {
        return IsValidUTF16(reinterpret_cast<const char16_t*>(sv.data()), sv.size());
    }

    bool IsValidWideChar(const std::vector<wchar_t>& data) {
        return IsValidUTF16(reinterpret_cast<const char16_t*>(data.data()), data.size());
    }

    // ================= 编码转换实现 =================

    // GBK → UTF-8
    std::string GBKToUTF8(const uint8_t* data, size_t size) {
        if (!data || size == 0) return "";

        // GBK → UTF-16
        int wideLen = MultiByteToWideChar(
            936, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            nullptr, 0
        );
        if (wideLen <= 0) return "";

        std::wstring wideStr(wideLen, 0);
        MultiByteToWideChar(
            936, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            &wideStr[0], wideLen
        );

        // UTF-16 → UTF-8
        int utf8Len = WideCharToMultiByte(
            CP_UTF8, 0,
            wideStr.c_str(),
            static_cast<int>(wideStr.size()),
            nullptr, 0,
            nullptr, nullptr
        );
        if (utf8Len <= 0) return "";

        std::string utf8Str(utf8Len, 0);
        WideCharToMultiByte(
            CP_UTF8, 0,
            wideStr.c_str(),
            static_cast<int>(wideStr.size()),
            &utf8Str[0], utf8Len,
            nullptr, nullptr
        );

        return utf8Str;
    }

    std::string GBKToUTF8(std::string_view sv) {
        return GBKToUTF8(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    std::string GBKToUTF8(std::basic_string_view<uint8_t> sv) {
        return GBKToUTF8(sv.data(), sv.size());
    }

    std::string GBKToUTF8(const char* str) {
        return str ? GBKToUTF8(reinterpret_cast<const uint8_t*>(str), strlen(str)) : "";
    }

    std::string GBKToUTF8(const std::vector<uint8_t>& data) {
        return GBKToUTF8(data.data(), data.size());
    }

    // UTF-8 → GBK
    std::string UTF8ToGBK(const uint8_t* data, size_t size) {
        if (!data || size == 0) return "";

        // UTF-8 → UTF-16
        int wideLen = MultiByteToWideChar(
            CP_UTF8, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            nullptr, 0
        );
        if (wideLen <= 0) return "";

        std::wstring wideStr(wideLen, 0);
        MultiByteToWideChar(
            CP_UTF8, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            &wideStr[0], wideLen
        );

        // UTF-16 → GBK
        int gbkLen = WideCharToMultiByte(
            936, 0,
            wideStr.c_str(),
            static_cast<int>(wideStr.size()),
            nullptr, 0,
            nullptr, nullptr
        );
        if (gbkLen <= 0) return "";

        std::string gbkStr(gbkLen, 0);
        WideCharToMultiByte(
            936, 0,
            wideStr.c_str(),
            static_cast<int>(wideStr.size()),
            &gbkStr[0], gbkLen,
            nullptr, nullptr
        );

        return gbkStr;
    }

    std::string UTF8ToGBK(std::string_view sv) {
        return UTF8ToGBK(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    std::string UTF8ToGBK(std::basic_string_view<uint8_t> sv) {
        return UTF8ToGBK(sv.data(), sv.size());
    }

    std::string UTF8ToGBK(const char* str) {
        return str ? UTF8ToGBK(reinterpret_cast<const uint8_t*>(str), strlen(str)) : "";
    }

    std::string UTF8ToGBK(const std::vector<uint8_t>& data) {
        return UTF8ToGBK(data.data(), data.size());
    }

    // UTF-16 → UTF-8
    std::string UTF16ToUTF8(const char16_t* data, size_t size) {
        if (!data || size == 0) return "";

        // UTF-16 → UTF-8
        int utf8Len = WideCharToMultiByte(
            CP_UTF8, 0,
            reinterpret_cast<LPCWCH>(data),
            static_cast<int>(size),
            nullptr, 0,
            nullptr, nullptr
        );
        if (utf8Len <= 0) return "";

        std::string utf8Str(utf8Len, 0);
        WideCharToMultiByte(
            CP_UTF8, 0,
            reinterpret_cast<LPCWCH>(data),
            static_cast<int>(size),
            &utf8Str[0], utf8Len,
            nullptr, nullptr
        );

        return utf8Str;
    }

    std::string UTF16ToUTF8(std::u16string_view sv) {
        return UTF16ToUTF8(sv.data(), sv.size());
    }

    std::string UTF16ToUTF8(const std::vector<char16_t>& data) {
        return UTF16ToUTF8(data.data(), data.size());
    }

    // UTF-8 → UTF-16
    std::u16string UTF8ToUTF16(const uint8_t* data, size_t size) {
        if (!data || size == 0) return u"";

        // UTF-8 → UTF-16
        int wideLen = MultiByteToWideChar(
            CP_UTF8, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            nullptr, 0
        );
        if (wideLen <= 0) return u"";

        std::u16string utf16Str(wideLen, 0);
        MultiByteToWideChar(
            CP_UTF8, 0,
            reinterpret_cast<LPCCH>(data),
            static_cast<int>(size),
            reinterpret_cast<LPWSTR>(utf16Str.data()),
            wideLen
        );

        return utf16Str;
    }

    std::u16string UTF8ToUTF16(std::string_view sv) {
        return UTF8ToUTF16(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    std::u16string UTF8ToUTF16(std::basic_string_view<uint8_t> sv) {
        return UTF8ToUTF16(sv.data(), sv.size());
    }

    std::u16string UTF8ToUTF16(const char* str) {
        return str ? UTF8ToUTF16(reinterpret_cast<const uint8_t*>(str), strlen(str)) : u"";
    }

    std::u16string UTF8ToUTF16(const std::vector<uint8_t>& data) {
        return UTF8ToUTF16(data.data(), data.size());
    }

    // wchar_t → UTF-8
    std::string WideCharToUTF8(const wchar_t* data, size_t size) {
        return UTF16ToUTF8(reinterpret_cast<const char16_t*>(data), size);
    }

    std::string WideCharToUTF8(std::wstring_view sv) {
        return WideCharToUTF8(sv.data(), sv.size());
    }

    std::string WideCharToUTF8(const std::vector<wchar_t>& data) {
        return WideCharToUTF8(data.data(), data.size());
    }

    // UTF-8 → wchar_t
    std::wstring UTF8ToWideChar(const uint8_t* data, size_t size) {
        auto utf16 = UTF8ToUTF16(data, size);
        return std::wstring(
            reinterpret_cast<const wchar_t*>(utf16.data()),
            utf16.size()
        );
    }

    std::wstring UTF8ToWideChar(std::string_view sv) {
        return UTF8ToWideChar(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
    }

    std::wstring UTF8ToWideChar(std::basic_string_view<uint8_t> sv) {
        return UTF8ToWideChar(sv.data(), sv.size());
    }

    std::wstring UTF8ToWideChar(const char* str) {
        return str ? UTF8ToWideChar(reinterpret_cast<const uint8_t*>(str), strlen(str)) : L"";
    }

    std::wstring UTF8ToWideChar(const std::vector<uint8_t>& data) {
        return UTF8ToWideChar(data.data(), data.size());
    }
}
